package probe.sound.code;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.SourceDataLine;

public class Beep1000Hz {
  
  public static void main(String[] args) throws Exception {
    System.out.println( "1000Hz beeping..." );
    
    double sampleRate = 48000;
    double beepDelay = 2;//delay in secods
    double A = 0.9;//=0...1 - loudness
    double Hz = 1000;
    
    AudioFormat b = new AudioFormat( (float)sampleRate, 16, 2, true, false );
    
    SourceDataLine.Info info = new DataLine.Info( SourceDataLine.class, b, 1024 );
    
    SourceDataLine line = (SourceDataLine)AudioSystem.getLine( info );
    line.addLineListener( new LineListener() {
      @Override
      public void update(LineEvent event) {
        System.out.println( System.currentTimeMillis() + ": --------------- " + event );
      }
    } );
    
    line.open();
    line.start();
    long started = System.currentTimeMillis();
    
    byte[] buf = new byte[line.getBufferSize()];
    
    int iCount = buf.length / 4;
    
    U: for (int u = 0; true; u++) {
      int bufferFilledOn = buf.length;
      I: for (int i = 0; i < iCount; i++) {
        
        int iSample = u * iCount + i;
        
        double t = ((double)iSample) / sampleRate;
        
        if (t > beepDelay) {
          bufferFilledOn = i * 4;
          break I;
        }
        
        double x = A * Math.sin( Hz * (2 * Math.PI) * t );
        
        int left = Util.toSignedWord( x );
        int right = Util.toSignedWord( x );
        
        Util.writeWord( buf, 4 * i + 0, true, left );
        Util.writeWord( buf, 4 * i + 2, true, right );
      }
      
      if (bufferFilledOn == 0) break U;
      
      int offset = 0;
      while (offset < bufferFilledOn) {
        int toWrite = line.available();
        if (offset + toWrite > bufferFilledOn) {
          toWrite = bufferFilledOn - offset;
          if (toWrite <= 0) break;
        }
        offset += line.write( buf, offset, toWrite );
      }
    }
    
    line.drain();
    
    System.out.println( "TIME: " + (System.currentTimeMillis() - started) );
    System.out.println( "line.getLongFramePosition() = " + line.getLongFramePosition() );
    
    line.stop();
    line.close();
    System.out.println( "END" );
  }
  
}
